<?php

namespace App\Kuafu\Pay\Service;

use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Config\Model\ConfigModel;
use App\Kuafu\Mybank\Model\MybankOrderWithholdRecordModel;
use App\Kuafu\Order\Model\OrderSplitModel;
use App\Kuafu\Pay\Enum\PayCacheEnum;
use App\Kuafu\Pay\Enum\PayCodeEnum;
use App\Kuafu\Pay\Exceptions\PayException;
use App\Kuafu\Pay\Model\PayStreamModel;
use App\Kuafu\Pay\Model\ShopPaymentModel;
use App\Kuafu\Shop\Enum\ShopCodeEnum;
use App\Kuafu\Shop\Exceptions\ShopException;
use App\Kuafu\Shop\Service\ShopService;
use App\Library\FeiShu\SendFs;
use App\Remote\Mybank\Remote;
use Illuminate\Support\Facades\Cache;
use Kuafu\GeneralFs\BuildFs;

class ShopPayService extends BaseService
{
    /**
     * 从缓存中获取支付配置
     * @param int $shopId
     * @param int $payChannel
     * @return array
     */
    public static function getPayConfigCache(int $shopId, int $payChannel): array
    {
        return Cache::remember(PayCacheEnum::getPayConfig($shopId, $payChannel), getSwitchCacheTime(60),
            function () use ($shopId, $payChannel) {
                return ShopPaymentModel::getPayConfig($shopId, $payChannel);
            });
    }

    /**
     * 关闭配置
     * @param int $shopId
     * @param int $payChannel
     */
    public static function sClose(int $shopId, int $payChannel): void
    {
        ShopPaymentModel::close($shopId, $payChannel);
        Cache::forget(PayCacheEnum::getPayConfig($shopId, $payChannel));
    }

    /**
     * 新增/更新
     * @param int $shopId
     * @param string $paymentName
     * @param int $payChannel
     * @param string $payConfig
     */
    public static function sAdd(
        int $shopId,
        string $paymentName,
        int $payChannel,
        string $payConfig
    ) {
        $res = ShopPaymentModel::addData(
            $shopId,
            $paymentName,
            $payChannel,
            $payConfig,
            255,
            1
        );
        Cache::forget(PayCacheEnum::getPayConfig($shopId, $payChannel));

        return $res;
    }

    public static function sDel(int $shopId): void
    {
        $payChannel = PayStreamModel::PAY_CHANNEL_FY;
        ShopPaymentModel::query()
                        ->where('shopId', $shopId)
                        ->where('payChannel', $payChannel)
                        ->update(['isDeleted' => 1]);

        Cache::forget(PayCacheEnum::getPayConfig($shopId, $payChannel));
    }

    /**
     * 新增富友支付配置
     * @param int $shopId
     * @param string $mchId
     * @param string $mchKey
     * @param string $orderPrefix
     * @return int
     * @throws ShopException
     */
    public static function addFyConfig(int $shopId, string $mchId, string $mchKey, string $orderPrefix): int
    {
        if (!$shopId || !$mchId || !$mchKey || !$orderPrefix) {
            throw new ShopException(ShopCodeEnum::ERR_ADD_SHOP_PAY_PARAM);
        }

        $shop = ShopService::getShopInfo($shopId);
        if (!$shop) {
            throw new ShopException(ShopCodeEnum::ERR_SHOP_ID_NO_EXIST);
        }

        $payChannel = PayStreamModel::PAY_CHANNEL_FY;

        // 判断店铺的支付配置是否已存在
        $shopPay = ShopPaymentModel::getPayConfig($shopId, $payChannel);
        if ($shopPay) {
            throw new ShopException(ShopCodeEnum::ERR_SHOP_BIND_PAY);
        }

        $payConfig = [
            'mch_id'       => $mchId,
            'mch_key'      => $mchKey,
            'order_prefix' => $orderPrefix,
        ];

        return self::sAdd($shopId, '富友直连', $payChannel, json_encode($payConfig))->id;
    }

    /**
     * 新增网商分账配置
     * @param int $shopId
     * @param array $config
     * @return int
     * @throws ShopException
     */
    public static function addMyBankShareConfig(int $shopId, array $config): int
    {
        $shop = ShopService::getShopInfo($shopId);
        if (!$shop) {
            throw new ShopException(ShopCodeEnum::ERR_SHOP_ID_NO_EXIST);
        }

        $payChannel = PayStreamModel::PAY_CHANNEL_MYBANK_CONFIG;

        // 判断店铺的支付配置是否已存在
        $shopPay = ShopPaymentModel::query()
                                   ->where('shopId', $shopId)
                                   ->where('payChannel', $payChannel)
                                   ->first();

        if ($shopPay) {

            $payConfig = json_decode($shopPay->payConfig, true);

            // 检查一下config是否一致
            if ($payConfig == $config) {
                return $shopPay->id;
            }

            // 如果有堂食订单，不允许改
            $order = OrderSplitModel::suffix($shopId)->query()->where('shopId', $shopId)->first();
            if ($order) {

                $content = "shopId: {$shopId} shopCode:{$shop->shopCode} {$shop->name}" . PHP_EOL . PHP_EOL;
                $content .= "db_config: " . json_encode($payConfig) . PHP_EOL . PHP_EOL;
                $content .= "new_config: " . json_encode($config) . PHP_EOL . PHP_EOL;

                BuildFs::newRobot(SendFs::ROBOT_WARNING)
                       ->setTitleContent('网商分账配置新增失败，配置已存在，且已有堂食订单。需人工校验', $content)
                       ->setAtUid('9efgbcdb')
                       ->setAtUid('3fgc8798')
                       ->send();

                throw new ShopException(ShopCodeEnum::ERR_SHOP_BIND_PAY);
            }

            $shopPay->isDeleted = 1;
            $shopPay->save();
        }

        return self::sAdd($shopId, PayStreamModel::PAY_CHANNEL_TEXT[$payChannel], $payChannel, json_encode($config))->id;
    }


    /**
     * 账户信息
     *
     * @param int $payChannel
     * @param int $company
     * @return array
     */
    public static function getOrderAccount(int $payChannel, int $company): array
    {
        $data   = [];
        $config = ConfigModel::getConfigByTypeKeyOne('pay', 'payOrderAccount');
        $value  = json_decode($config->value ?? '', true) ?? [];
        if ($value) {
            collect($value)
                ->where('payChannel', $payChannel)
                ->map(function ($item) use ($company, &$data) {
                    foreach ($item['company'] ?? [] as $v) {
                        if ($company == $v['id']) {
                            $data = [
                                'payeeId'   => $v['payeeId'],
                                'payeeType' => $v['payeeType'],
                            ];
                            break;
                        }
                    }
                });
        }
        if (!$data) {
            $data = [
                'payeeId'   => Remote::getKfosBankMerchantId(),
                'payeeType' => MybankOrderWithholdRecordModel::WITHHOLD_MERCHANT,
            ];
        }
        return $data;
    }
}
